<script setup name="YEditor">
import "@wangeditor/editor/dist/css/style.css"; 
import { getToken, tokenKey } from "@/utils/auth";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { v4 as uuidv4 } from "uuid";
 
const props = defineProps({
  editorId: { type: String, default: () => `editor-${uuidv4()}` },
  modelValue: { type: String, default: "" },
  placeholder: { type: String, default: "请输入内容" },
  height: { type: String, default: "400px" },
  // 初始模式：edit(编辑) | preview(预览)
  initialMode: { type: String, default: "edit", validator: (val) => ["edit", "preview"].includes(val) },
});
 
const emit = defineEmits(["update:modelValue", "modeChange"]);
 
const loading = ref(false);
const editorRef = shallowRef();
const valueHtml = ref("");
const mode = "default";
const currentMode = ref(props.initialMode); 
 
const toolbarConfig = computed(() => ({
  excludeKeys: currentMode.value  === "preview" ? ["fullScreen"] : [],
}));
 
const editorConfig = computed(() => ({
  placeholder: props.placeholder, 
  readOnly: currentMode.value  === "preview",
  autoFocus: currentMode.value  === "edit",
  scroll: true,
  MENU_CONF: getMenuConf(),
}));
 
function getMenuConf() {
  const headers = { Authorization: "Bearer " + getToken(tokenKey.access)  };
  
  return {
    uploadImage: getUploadConfig(headers, "image/*", 2 * 1024 * 1024, 10),
    insertImage: {
      onInsertedImage(imageNode) {
        if (imageNode == null) return;
        const { src, alt, href } = imageNode;
      },
    },
    uploadVideo: getUploadConfig(headers, "video/*", 60 * 1024 * 1024, 3),
  };
}
 
function getUploadConfig(headers, allowedTypes, maxFileSize, maxNumberOfFiles) {
  return {
    server: "/api/sys/file/",
    headers: headers,
    fieldName: "file",
    maxFileSize,
    maxNumberOfFiles,
    allowedFileTypes: allowedTypes,
    withCredentials: true,
    timeout: 15 * 1000,
    customInsert(res, insertFn) {
      const url = import.meta.env.VITE_APP_BASE_API  + res.data.file; 
      if (allowedTypes[0].includes("image")) {
        const alt = res.data.name; 
        const href = window.location.href; 
        insertFn(url, alt, href);
      } else {
        insertFn(url);
      }
    },
    onSuccess(file, res) {
      console.log(`${file.name}  上传成功`, res);
    },
    onFailed(file, res) {
      console.log(`${file.name}  上传失败`, res);
    },
    onError(file, err, res) {
      console.log(`${file.name}  上传出错`, err, res);
    },
  };
}
const handleCreated = (editor) => {
  editorRef.value  = editor;
};
 
const handleChange = (editor) => {
  emit("update:modelValue", editor.getHtml()); 
};
 
watch(() => props.modelValue,  (newVal) => {
  if (newVal !== valueHtml.value)  {
    valueHtml.value  = newVal;
  }
});
 
watch(() => props.initialMode,  (newVal) => {
  currentMode.value  = newVal;
});
 
onMounted(() => {
  loading.value  = true;
  valueHtml.value  = props.modelValue; 
  nextTick(() => {
    loading.value  = false;
  });
});
 
onBeforeUnmount(() => {
  if (editorRef.value)  {
    editorRef.value.destroy(); 
    editorRef.value  = null;
  }
});
 
const customPaste = (editor, event, callback) => {
  callback(true);
};
</script>
 
<template>
  <div class="y-editor-container" :id="editorId">
    <div>
      <Toolbar
        v-if="currentMode === 'edit'"
        :key="editorId + '-toolbar'"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
        class="editor-toolbar"
      />
    </div>
    
    <div v-loading="loading" class="editor-content-container">
      <Editor
        v-if="currentMode === 'edit'"
        :key="editorId + '-editor'"
        :defaultConfig="editorConfig"
        :mode="mode"
        v-model="valueHtml"
        :style="{ height }"
        @onCreated="handleCreated"
        @onChange="handleChange"
        @customPaste="customPaste"
        class="editor-content"
      />
      
      <div
        v-else 
        class="preview-content"
        :style="{ height, overflowY: 'auto' }"
        v-html="valueHtml"
      ></div>
    </div>
  </div>
</template>
 
<style scoped>
.y-editor-container {
  width: 100%;
  border: 1px solid #ccc;
  z-index: 100;
}
 
.editor-toolbar {
  flex: 1;
  border: none;
}
 
.mode-toggle {
  margin-left: 10px;
}
 
.editor-content-container {
  position: relative;
}
 
.editor-content,
.preview-content {
  overflow-y: auto;
  padding: 10px;
}
 
.preview-content {
  background-color: #fff;
}
 
/* 预览模式下的图片样式调整 */
.preview-content img {
  max-width: 100%;
  height: auto;
}

/* 预览模式下的视频样式调整 */
.preview-content video {
  max-width: 100%;
  height: auto;
}
</style>